/**
 * Require: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
 * Require: <script src="https://epp-jslib.googlecode.com/hg-history/tip/src/epp-string.js"></script>
 * Usage:   <script src="https://epp-jslib.googlecode.com/hg-history/tip/src/epp-date-time.js"></script>
 **/

function EPPTime(hours, minutes, negative) {
    this.hours = hours || 0;
    this.minutes = minutes || 0;
    this.negative = negative || false;
    if(!Number.isInteger(this.hours) || !Number.isInteger(this.minutes)) throw new Error("Invalid time");
}

EPPTime.prototype.inMinutes = function() {
    var signal = this.negative ? -1 : 1;
    return  (this.hours * 60 + this.minutes )* signal;
};

EPPTime.prototype.plus = function(time) {
    var m1 = this.inMinutes();
    var m2 = time.inMinutes();
    return EPPTime.fromMinutes(m1+m2);
};

EPPTime.prototype.minus = function(time) {
    var m1 = this.inMinutes();
    var m2 = time.inMinutes();
    return EPPTime.fromMinutes(m1-m2);
};

EPPTime.prototype.toString = function() {
    var signal = this.negative ? '-' : '';
    return signal + this.hours.toString().pad(2) + ':' + this.minutes.toString().pad(2);
};

/* static */

EPPTime.fromMinutes = function(minutes) {
    var negative = minutes < 0;
    minutes = Math.abs(minutes);
    var h = parseInt(minutes/60, 10);
    var m = minutes - (h*60);
    return new EPPTime(h,m, negative);
}

EPPTime.fromString = function(hhmmAsText) {
    var negative = (hhmmAsText.indexOf('-') === 0);
    if(hhmmAsText.indexOf(':') < 0) throw new Error("Invalid time");
    var hhmm = hhmmAsText.split(':').map(function(it){ return parseInt(it, 10); });
    if(!Number.isInteger(hhmm[0]) || !Number.isInteger(hhmm[1])) throw new Error("Invalid time");
    return new EPPTime(hhmm[0],hhmm[1], negative);
}

EPPTime.isTime = function (hhmmAsText) {
    try {
        var time = EPPTime.fromString(hhmmAsText);
        return Number.isInteger(time.hours) && Number.isInteger(time.minutes);
    } catch(any) { return false; }
}

EPPTime.now = function() {
    var dt = new Date();
    return new EPPTime(dt.getHours(), dt.getMinutes());
};

EPPTime.calculaHorasTrabalhadas = function(arrayEntradasESaidasString, consideraHoraCorrente) {
    var arrayClone = arrayEntradasESaidasString.clone();
    consideraHoraCorrente = (consideraHoraCorrente !== undefined) ? consideraHoraCorrente :  true;
    var horasTrabalhadas = new EPPTime();
    while(arrayClone.length > 1) {
        try {
            var entradaString = arrayClone.shift();
            var saidaString   = arrayClone.shift();
            var entrada = EPPTime.fromString(entradaString);
            var saida;
            try {
                saida = EPPTime.fromString(saidaString);
            } catch(any) {
                if(consideraHoraCorrente) {
                    saida = EPPTime.now();
                } else {
                    console.log('Entrada sem saída [' + entradaString + ' - ' + saidaString + ']');
                    throw any;
                }
            }
            if(saida.inMinutes() > entrada.inMinutes()) {
                horasTrabalhadas = horasTrabalhadas
                    .plus(saida)
                    .minus(entrada);
            }
        } catch(any) {}
    }
    return horasTrabalhadas;
};

/* Date */

Date.prototype.toStringDMY = function() {
    return [this.getDate().toString().pad(2), (this.getMonth()+1).toString().pad(2), this.getFullYear().toString().pad(4)].join('/');
};

function EPPDate() {}

EPPDate.ehHoje = function(dataStringDMY) {
    return dataStringDMY === new Date().toStringDMY();
};